package koala.kuangjiademo.net;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;

import java.io.Serializable;

import koala.kuangjiademo.util.Helper;

public abstract class OnResponseListener<T extends Serializable> implements DialogInterface.OnCancelListener {
    protected Context context;
    final boolean successOnly;
    private final boolean autoDismissProgress;
    private long startTime, endTime;
    private final ProgressStyle progressStyle;

    public OnResponseListener(Context context) {
        this(context, true, true);
    }

    public OnResponseListener(Context context, boolean successOnly, boolean autoDismissProgress) {
        this.context = context;
        this.successOnly = successOnly;
        this.autoDismissProgress = autoDismissProgress;
        startTime = System.currentTimeMillis();
        progressStyle = getProgressStyle();
    }

    protected ProgressStyle getProgressStyle() {
        return new DialogProgressStyle(context, this);
    }

    public void showProgress() {
        progressStyle.showProgress();
    }

    public void dismissProgress() {
        progressStyle.dismissProgress();
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        cancel();
    }

    void onThreadResponse(final IResponseStatus status, final T response) {
        endTime = System.currentTimeMillis();
        Runnable action = new Runnable() {
            @Override
            public void run() {
                if (autoDismissProgress) dismissProgress();
                if (successOnly) {
                    if (status.isSuccess()) {
                        onResponse(status, response);
                    } else {
                        onFailed(status);
                    }
                } else onResponse(status, response);
            }
        };
        if (getDelayToTime() > 0 && status.isSuccess()) {
            delayTo(action, getDelayToTime());
        } else run(context, action);
    }

    /**
     * @return delay time In Milliseconds
     */
    protected long getDelayToTime() {
        return 0;
    }

    private void delayTo(final Runnable runnable, long delay) {
        delay = delay - (endTime - startTime);
        if (delay > 0 && context instanceof Activity) {
            final long finalDelay = delay;
            ((Activity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    new Handler().postDelayed(runnable, finalDelay);
                }
            });
        } else Helper.startRunnable(context, runnable);
    }

    public abstract void onResponse(IResponseStatus status, T response);

    protected void onFailed(IResponseStatus status) {
        dismissProgress();
        Helper.showDialog(context, status.getMessage());
    }

    private void run(Context context, Runnable action) {
        if (!isCanceled()) Helper.startRunnable(context, action);
    }

    void setCancelable(Cancelable cancelable) {
        this.cancelable = cancelable;
    }

    private Cancelable cancelable;

    private void cancel() {
        if (cancelable != null) cancelable.cancel();
    }

    private boolean isCanceled() {
        return cancelable != null && cancelable.isCanceled() || context instanceof Activity && ((Activity) context).isFinishing();
    }
}
